package com.ruoyi.web.controller.card;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.LocalDateTimeUtil;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.ruoyi.common.exception.user.UserInvalidException;
import com.ruoyi.service.card.IFudiCardService;
import com.ruoyi.service.card.IGshCardService;
import com.ruoyi.util.DateUtil;
import com.ruoyi.util.GshQrcodeUtil;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.common.bean.result.WxMediaUploadResult;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpMessageRouter;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.io.File;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Map;

/**
 * TODO
 *
 * @author chenchuan2
 * @date 2024-04-05 18:09:48
 */
@RestController
@RequestMapping("/card-api")
@Slf4j
public class CardController {

    @Autowired
    private WxMpService wxService;

    @Autowired
    private WxMpMessageRouter messageRouter;

    @Autowired
    private IGshCardService gshCardService;

    @Autowired
    private IFudiCardService fudiCardService;

    private static final Map<String, List<String>> map = Maps.newHashMap();

    private static final List<String> whiteList = Lists.newArrayList("996996","123321", "bsb");

    static {
        //map.put("996996", Lists.newArrayList("GSH","FUDI"));
        //map.put("888888", Lists.newArrayList("GSH","FUDI"));
        //map.put("bsb", Lists.newArrayList("GSH","FUDI"));

        map.put("165525-1", Lists.newArrayList("GSH", "FUDI"));
        map.put("634711-2", Lists.newArrayList("GSH", "FUDI"));
        map.put("97258-3", Lists.newArrayList("GSH", "FUDI"));
        map.put("956619-4", Lists.newArrayList("GSH", "FUDI"));
        map.put("353247-5", Lists.newArrayList("GSH", "FUDI"));
        map.put("320990-6", Lists.newArrayList("GSH", "FUDI"));
        map.put("579828-7", Lists.newArrayList("GSH", "FUDI"));

    }


    @GetMapping("/checkCode")
    public CheckCodeDTO checkCode(@RequestParam(name = "code") String code) {
        CheckCodeDTO checkCodeDTO = new CheckCodeDTO();
        if (whiteList.contains(code.toLowerCase())) {
            checkCodeDTO.setRules(Lists.newArrayList("GSH", "FUDI"));
            return checkCodeDTO;
        }
//        if (code.equalsIgnoreCase("996996")) {
//            //获取当前小时
//            int hour = LocalDateTime.now().getHour();
//            if (hour % 2 == 0) {
//                checkCodeDTO.setRules(Lists.newArrayList("GSH", "FUDI"));
//                return checkCodeDTO;
//            } else {
//                throw new RuntimeException("验证码使用人数过多，小程序右下角【联系客服】获取最新验证码");
//            }
//        }
        String realCode = code.toLowerCase() + "-" + LocalDateTime.now().getDayOfWeek().getValue();
        List<String> list = map.get(realCode);
        if (CollectionUtils.isEmpty(list)) {
            throw new RuntimeException("验证码使用人数过多，小程序右下角【联系客服】获取最新验证码");
        }
        checkCodeDTO.setRules(list);
        return checkCodeDTO;
    }

    @GetMapping("/qrcode")
    public QrCodeDTO qrcode(@RequestParam(name = "type") String type) {
        QrCodeDTO qrCodeDTO = new QrCodeDTO();
        switch (type) {
            case "gsh":
                qrCodeDTO.setMember_no(gshCardService.gshCardMemberNo());
                break;
            case "fudi":
                qrCodeDTO.setQrCode(fudiCardService.fudiQrCode());
                break;
            default:
                throw new IllegalArgumentException("不支持的卡类型");
        }
        return qrCodeDTO;
    }


    @GetMapping("testFile")
    public String testFile() {
        String cardMemberNo = gshCardService.gshCardMemberNo();
        String filePath = GshQrcodeUtil.generateQRCodeWithImage(cardMemberNo);
        WxMediaUploadResult wxMediaUploadResult = null;
        try {
            wxMediaUploadResult = wxService.getMaterialService().mediaUpload(WxConsts.MaterialType.IMAGE, new File(filePath));
        } catch (WxErrorException e) {
            e.printStackTrace();
        }
        return wxMediaUploadResult.getUrl();
    }

    @PostMapping(path = "/callback", produces = "application/xml; charset=UTF-8")
    public String callBack(@RequestBody String requestBody,
                           @RequestParam("signature") String signature,
                           @RequestParam("timestamp") String timestamp,
                           @RequestParam("nonce") String nonce,
                           @RequestParam("openid") String openid,
                           @RequestParam(name = "encrypt_type", required = false) String encType,
                           @RequestParam(name = "msg_signature", required = false) String msgSignature
    ) {
        log.info("======callback========[{}]", openid);
        if (!wxService.checkSignature(timestamp, nonce, signature)) {
            throw new IllegalArgumentException("非法请求，可能属于伪造的请求！");
        }

        String out = null;
        if (encType == null) {
            // 明文传输的消息
            WxMpXmlMessage inMessage = WxMpXmlMessage.fromXml(requestBody);
            WxMpXmlOutMessage outMessage = this.route(inMessage);
            if (outMessage == null) {
                return "";
            }

            out = outMessage.toXml();
        } else if ("aes".equalsIgnoreCase(encType)) {
            // aes加密的消息
            WxMpXmlMessage inMessage = WxMpXmlMessage.fromEncryptedXml(requestBody, wxService.getWxMpConfigStorage(),
                    timestamp, nonce, msgSignature);
            log.debug("\n消息解密后内容为：\n{} ", inMessage.toString());
            WxMpXmlOutMessage outMessage = this.route(inMessage);
            if (outMessage == null) {
                return "";
            }
            out = outMessage.toEncryptedXml(wxService.getWxMpConfigStorage());
        }

        log.debug("\n组装回复信息：{}", out);
        return out;
    }

    private WxMpXmlOutMessage route(WxMpXmlMessage message) {
        try {
            return this.messageRouter.route(message);
        } catch (Exception e) {
            log.error("路由消息时出现异常！", e);
        }

        return null;
    }


}
